<template>
  <div>
    <a-upload-dragger
      :fileList="fileList"
      name="file"
      @change="handleChange"
      @drop="handleDrop"
      :beforeUpload="beforeUpload"
      :accept="getStringAccept"
      :multiple="multiple"
      :max-count="maxNumber"
    >
      <p class="ant-upload-drag-icon">
        <inbox-outlined />
      </p>
      <p class="ant-upload-text">点击 或 拖拽文件到此处</p>
      <p class="ant-upload-hint"> {{ getHelpText }} </p>
    </a-upload-dragger>
  </div>
</template>

<script setup lang="ts">
  import { UploadChangeParam, UploadProps } from 'ant-design-vue';
  import { FileItem, UploadResultStatus } from './types/typing';
  import { isFunction } from '/@/utils/is';
  import { warn } from '/@/utils/log';
  import { basicProps } from './props';
  import { buildUUID } from '/@/utils/uuid';
  import { useUploadType } from './hooks/useUpload';

  const props = defineProps(basicProps);

  // const attrs = useAttrs();

  const emits = defineEmits(['change', 'drop']);

  const isUploadingRef = ref(false);

  const { createMessage } = useMessage();

  const { accept, helpText, maxNumber, maxSize } = toRefs(props);

  const { getStringAccept, getHelpText } = useUploadType({
    acceptRef: accept,
    helpTextRef: helpText,
    maxNumberRef: maxNumber,
    maxSizeRef: maxSize,
  });

  const fileList = ref<UploadProps['fileList']>([
    // {
    //   uid: '1',
    //   name: 'xxx.png',
    //   status: 'done',
    //   response: 'Server Error 500', // custom error message to show
    //   url: 'http://www.baidu.com/xxx.png',
    // },
    // {
    //   uid: '3',
    //   name: 'zzz.png',
    //   status: 'error',
    //   response: 'Server Error 500', // custom error message to show
    //   url: 'http://www.baidu.com/zzz.png',
    // },
  ]);

  const handleChange = (info: UploadChangeParam) => {
    const status = info.file.status;
    if (status !== 'uploading') {
      console.log(info.file, info.fileList);
    }
    if (status === 'done') {
      createMessage.success(`${info.file.name} 上传成功`);
    } else if (status === 'error') {
      createMessage.error(`${info.file.name} 上传失败`);
    }
    // emits('change', info);
  };

  function handleDrop(e: DragEvent) {
    emits('drop', e);
  }

  async function uploadApiByItem(item: FileItem) {
    const { api } = props;
    if (!api || !isFunction(api)) {
      return warn('upload api must exist and be a function');
    }
    try {
      item.status = UploadResultStatus.UPLOADING;
      const ret = await props.api(
        {
          data: {
            ...(props.uploadParams || {}),
          },
          file: item.file,
          name: props.name,
          filename: props.filename,
        },
        function onUploadProgress(progressEvent: ProgressEvent) {
          const complete = ((progressEvent.loaded / progressEvent.total) * 100) | 0;
          item.percent = complete;
        },
      );
      const { data } = ret;
      item.status = UploadResultStatus.SUCCESS;
      item.responseData = data;
      return {
        success: true,
        error: null,
      };
    } catch (e) {
      console.log(e);
      item.status = UploadResultStatus.ERROR;
      return {
        success: false,
        error: e,
      };
    }
  }

  // 上传前校验
  function beforeUpload(file: File) {
    const { size, name } = file;
    const { maxSize } = props;
    // 设置最大值，则判断
    if (maxSize && file.size / 1024 / 1024 >= maxSize) {
      createMessage.error(t('component.upload.maxSizeMultiple', [maxSize]));
      return false;
    }

    const commonItem = {
      uid: buildUUID(),
      file,
      size,
      name,
      percent: 0,
      type: name.split('.').pop(),
    };
    // 生成图片缩略图
    // if (checkImgType(file)) {
    //   // beforeUpload，如果异步会调用自带上传方法
    //   // file.thumbUrl = await getBase64(file);
    //   getBase64WithFile(file).then(({ result: thumbUrl }) => {
    //     fileListRef.value = [
    //       ...unref(fileListRef),
    //       {
    //         thumbUrl,
    //         ...commonItem,
    //       },
    //     ];
    //   });
    // } else {
    fileList.value = [...unref(fileList), commonItem];
    // }

    handleStartUpload();

    //禁止自动上传
    return false;
  }

  async function handleStartUpload() {
    try {
      isUploadingRef.value = true;
      // 只上传不是成功状态的
      const uploadFileList =
        fileList.value.filter((item) => item.status !== UploadResultStatus.SUCCESS) || [];
      const data = await Promise.all(
        uploadFileList.map((item) => {
          return uploadApiByItem(item);
        }),
      );
      isUploadingRef.value = false;

      // 生产环境:抛出错误
      const errorList = data.filter((item: any) => !item.success);
      if (errorList.length > 0) throw errorList;
    } catch (e) {
      isUploadingRef.value = false;
      throw e;
    } finally {
      emits(
        'change',
        fileList.value.filter((item) => item.status == UploadResultStatus.SUCCESS),
      );
    }
  }
</script>

<style lang="less" scoped></style>
